﻿using System;
using System.Collections.Generic;
using CivilRegistry.ControlledModel.Extensions;

namespace CivilRegistry.ControlledModel
{
    /// <summary>
    /// The super admin object.
    /// </summary>
    public partial class SuperAdmin: User
    {
        #region Methods

        #region Finder Methods

        /// <summary>
        /// Finds the <see cref="SuperAdmin"/> by Id.
        /// </summary>
        /// <param name="id">The id of the <see cref="SuperAdmin"/>.</param>
        /// <returns>Found <see cref="SuperAdmin"/> object, null if not found.</returns>
        public static SuperAdmin FindById(int id)
        {
            return (SuperAdmin)repository.FindBy(user => user.UserId == id && user is SuperAdmin);
        }

        /// <summary>
        /// Retrives the deactive <see cref="SuperAdmin"/>s.
        /// </summary>
        /// <returns>The deactive <see cref="SuperAdmin"/>s.</returns>
        public static List<SuperAdmin> GetDeactiveRecords()
        {
            List<SuperAdmin> superAdminList = new List<SuperAdmin>();
            repository.FindAll(user => user.DeactivateReason != null).ForEach(user => superAdminList.Add((SuperAdmin)user));
            return superAdminList;
        }

        #endregion

        #region Controling Methods

        /// <summary>
        /// To update the <see cref="User"/> accout.
        /// </summary>
        /// <typeparam name="T">The type of the <see cref="User"/>.</typeparam>
        /// <param name="user">The <see cref="User"/> to update.</param>
        /// <returns>Updated <see cref="User"/>.</returns>
        public T Modify<T>(T user) where T : User
        {
            user.Required("user");

            if (typeof(T) == typeof(Person))
                throw new ApplicationException("SuperAdmin cannot modify the person account.");

            return (T)this.Update(user);
        }

        /// <summary>
        /// To create a <see cref="User"/>.
        /// </summary>
        /// <typeparam name="T">The type of the <see cref="User"/>.</typeparam>
        /// <param name="user">The <see cref="User"/> to create.</param>
        /// <returns>Created <see cref="User"/>.</returns>
        /// <exception cref="ApplicationException">The <see cref="SuperAdmin"/> cannot create a <see cref="Person"/>.</exception>
        public T CreateUser<T>(T user) where T: User
        {
            user.Required("user");

            if (typeof(T) == typeof(Person))
                throw new ApplicationException("SuperAdmin cannot create a Person account.");

            user.Password = GetRandomPassword(6);

            return (T)this.Insert(user);
        }

        /// <summary>
        /// Generates a random password.
        /// </summary>
        /// <param name="length">The length of the password.</param>
        /// <returns>Generated password.</returns>
        private string GetRandomPassword(int length)
        {
            char[] chars = "$%#@!*abcdefghijklmnopqrstuvwxyz1234567890?;ABCDEFGHIJKLMNOPQRSTUVWXYZ^&".ToCharArray();
            string password = string.Empty;
            Random random = new Random();

            for (int i = 0; i < length; i++)
            {
                int x = random.Next(1, chars.Length);
                //Don't Allow Repetation of Characters
                if (!password.Contains(chars.GetValue(x).ToString()))
                    password += chars.GetValue(x);
                else
                    i--;
            }
            return password;
        }

        #endregion

        #endregion
    }
}